package com.doubao.chat.service.impl;

import com.coze.openapi.client.chat.CreateChatReq;
import com.coze.openapi.client.chat.CreateChatResp;
import com.coze.openapi.client.chat.model.ChatPoll;
import com.coze.openapi.client.connversations.message.model.Message;
import com.coze.openapi.service.auth.TokenAuth;
import com.coze.openapi.service.config.Consts;
import com.coze.openapi.service.service.CozeAPI;
import com.doubao.chat.dto.MessageProviderInfo;
import com.doubao.chat.entity.ChatMessage;
import com.doubao.chat.service.AIProviderService;
import com.doubao.common.exception.BusinessException;
import com.doubao.common.result.Result;
import com.doubao.device.entity.SmartDevice;
import com.doubao.device.service.SmartDeviceService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * AI提供商服务实现类 - 使用Coze SDK
 */
@Service
@Slf4j
public class CozeSDKProviderServiceImpl implements AIProviderService {

    private final SmartDeviceService deviceService;

    // 用于缓存不同API Key的Coze客户端实例
    private final Map<String, CozeAPI> cozeClientCache = new ConcurrentHashMap<>();

    @Value("${chat.ai-providers.coze.default-api-key:pat_dXmlpdKw5tnnHUeQTbzLpKYP40lMKYXTkNxqyJrvj65qgy4B9y8iS6fueCLurXdP}")
    private String cozeDefaultApiKey;

    @Value("${chat.ai-providers.coze.name:扣子AI}")
    private String cozeProviderName;

    @Value("${chat.ai-providers.coze.request-config.timeout:30000}")
    private int cozeTimeout;

    public CozeSDKProviderServiceImpl(SmartDeviceService deviceService) {
        this.deviceService = deviceService;
    }

    @PostConstruct
    public void init() {
        log.info("初始化Coze SDK客户端");
        // 初始化默认客户端
        getOrCreateCozeClient(cozeDefaultApiKey);
        log.info("Coze SDK客户端初始化完成");
    }

    /**
     * 获取或创建Coze客户端实例
     * @param apiKey API密钥
     * @return Coze客户端实例
     */
    private CozeAPI getOrCreateCozeClient(String apiKey) {
        return cozeClientCache.computeIfAbsent(apiKey, key -> {
            log.info("创建新的Coze客户端，API Key: {}", maskApiKey(key));
            TokenAuth authCli = new TokenAuth(key);
            return new CozeAPI.Builder()
                    .baseURL(Consts.COZE_CN_BASE_URL)
                    .auth(authCli)
                    .readTimeout(cozeTimeout)
                    .build();
        });
    }

    /**
     * 掩码API Key，只显示前5位和后5位
     */
    private String maskApiKey(String apiKey) {
        if (apiKey == null || apiKey.length() <= 10) {
            return "****";
        }
        return apiKey.substring(0, 5) + "..." + apiKey.substring(apiKey.length() - 5);
    }

    @Override
    public Result<MessageProviderInfo> getProviderInfo(Long deviceId) {
        try {
            // 获取智能体
            SmartDevice device = deviceService.getById(deviceId);
            if (device == null) {
                return Result.failed("智能体不存在");
            }

            Long providerId = device.getAiProviderId();
            String modelId = device.getAiModelId();

            // 构建提供商信息
            MessageProviderInfo providerInfo = new MessageProviderInfo();
            providerInfo.setProviderId(providerId);
            providerInfo.setModelId(modelId);
            providerInfo.setProviderName(cozeProviderName);
            providerInfo.setProviderCode("coze");
            providerInfo.setModelName("Coze Bot");
            providerInfo.setModelCode("coze-bot");
            providerInfo.setNeedsBotId(true);

            return Result.success(providerInfo);
        } catch (Exception e) {
            log.error("获取AI提供商信息异常", e);
            return Result.failed("获取AI提供商信息异常: " + e.getMessage());
        }
    }

    @Override
    public Result<String> getSystemPrompt(Long deviceId) {
        try {
            // 获取智能体
            SmartDevice device = deviceService.getById(deviceId);
            if (device == null) {
                return Result.failed("智能体不存在");
            }

            // 获取提示词
            String prompt = device.getPrompt();
            if (!StringUtils.hasText(prompt)) {
                return Result.success(""); // 返回空字符串作为默认提示词
            }

            return Result.success(prompt);
        } catch (Exception e) {
            log.error("获取系统提示词异常", e);
            return Result.failed("获取系统提示词异常: " + e.getMessage());
        }
    }

    @Override
    public Result<String> sendMessageToProvider(Long deviceId, String systemPrompt, List<ChatMessage> contextMessages, String userMessage) {
        try {
            // 获取智能体
            SmartDevice device = deviceService.getById(deviceId);
            if (device == null) {
                return Result.failed("智能体不存在");
            }

            // 使用设备配置的API密钥，如果没有则使用默认密钥
            String apiKey = StringUtils.hasText(device.getApiKey()) ? device.getApiKey() : cozeDefaultApiKey;
            if (!StringUtils.hasText(apiKey)) {
                return Result.failed("扣子API密钥未配置");
            }

            // 获取或创建Coze客户端
            CozeAPI cozeClient = getOrCreateCozeClient(apiKey);

            // 获取bot ID (使用设备的ai_model_id)
            String botId = String.valueOf(device.getAiModelId());
            if (!StringUtils.hasText(botId)) {
                return Result.failed("智能体模型ID为空");
            }

            // 使用固定用户ID - userId字段作为标识符，确保会话连续性
            // 格式: user_设备ID_用户ID
            String userId = "user_" + device.getId() + "_" + device.getUserId();

            log.info("调用扣子SDK - Bot ID: {}, 用户ID: {}", botId, userId);

            // 转换历史消息为SDK消息格式
            List<Message> messages = convertMessages(contextMessages);

            // 添加当前用户消息
            messages.add(Message.buildUserQuestionText(userMessage));

            log.info("消息数量: {}", messages.size());

            // 构建聊天请求
            CreateChatReq req = CreateChatReq.builder()
                    .botID(botId)
                    .userID(userId)
                    .messages(messages)
                    .stream(false)  // 使用非流式响应
                    .autoSaveHistory(true)  // 启用自动保存历史
                    .build();

            // 添加系统提示词（如果有）
            if (StringUtils.hasText(systemPrompt)) {
                Map<String, String> metaData = new HashMap<>();
                metaData.put("system_prompt", systemPrompt);
                req.setMetaData(metaData);
            }

            try {
                // 使用createAndPoll方法直接获取完整响应
                ChatPoll chatPoll = cozeClient.chat().createAndPoll(req);

                if (chatPoll != null && chatPoll.getMessages() != null && !chatPoll.getMessages().isEmpty()) {
                    Message lastMessage = chatPoll.getMessages().get(chatPoll.getMessages().size() - 1);
                    log.info("获取到完整响应");
                    return Result.success(lastMessage.getContent());
                } else {
                    throw new BusinessException("扣子API返回空响应");
                }
            } catch (Exception e) {
                log.warn("Poll方式获取响应失败: {}", e.getMessage());

                // 尝试直接使用create方法
                CreateChatResp response = cozeClient.chat().create(req);

                if (response != null && response.getChat() != null) {
                    // 简单返回一个提示信息，让客户端自行刷新获取最新响应
                    log.info("消息已发送，需要客户端刷新获取响应");
                    return Result.success("消息已发送，请刷新查看回复");
                } else {
                    throw new BusinessException("扣子API返回空响应");
                }
            }
        } catch (Exception e) {
            log.error("发送消息到扣子AI异常", e);
            return Result.failed("发送消息到扣子AI异常: " + e.getMessage());
        }
    }

    /**
     * 转换消息格式
     */
    private List<Message> convertMessages(List<ChatMessage> contextMessages) {
        List<Message> result = new ArrayList<>();
        if (contextMessages == null || contextMessages.isEmpty()) {
            return result;
        }

        for (ChatMessage msg : contextMessages) {
            if ("user".equals(msg.getRole())) {
                result.add(Message.buildUserQuestionText(msg.getContent()));
            } else if ("assistant".equals(msg.getRole())) {
                result.add(Message.buildAssistantAnswer(msg.getContent()));
            } else if ("system".equals(msg.getRole())) {
                // 系统提示词通过metaData参数传递，这里忽略
                continue;
            }
        }

        return result;
    }
}